package zj.it.bhne.gridengineeringsurvey.activity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ListView;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.offline.MKOLSearchRecord;
import com.baidu.mapapi.map.offline.MKOLUpdateElement;
import com.baidu.mapapi.map.offline.MKOfflineMap;
import com.baidu.mapapi.map.offline.MKOfflineMapListener;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

import zj.it.bhne.gridengineeringsurvey.BaseActivity;
import zj.it.bhne.gridengineeringsurvey.R;
import zj.it.bhne.gridengineeringsurvey.myutils.map.MySearchView;
import zj.it.bhne.gridengineeringsurvey.myutils.map.adapters.OfflineExpandableListAdapter;
import zj.it.bhne.gridengineeringsurvey.myutils.map.adapters.OfflineMapAdapter;
import zj.it.bhne.gridengineeringsurvey.myutils.map.adapters.OfflineMapManagerAdapter;
import zj.it.bhne.gridengineeringsurvey.myutils.map.interfaces.OnOfflineItemStatusChangeListener;
import zj.it.bhne.gridengineeringsurvey.myutils.map.models.OfflineMapItem;
import zj.it.bhne.gridengineeringsurvey.myutils.map.utils.CsqBackgroundTask;
import zj.it.bhne.gridengineeringsurvey.myutils.map.utils.ToastUtil;

/**
 * 离线地图的活动
 */
public class BaiduOfflineMapActivity extends BaseActivity
        implements MKOfflineMapListener, OnOfflineItemStatusChangeListener, View.OnClickListener {

    // ------------------------ Constants ------------------------

    // ------------------------- Fields --------------------------

    private ViewPager viewpager;
    //private PagerTabStrip pagertab;

    private MySearchView svDown;

    private MySearchView svAll;
    private ExpandableListView lvWholeCountry;
    private ListView lvSearchResult;

    private List<View> views = new ArrayList<>(2);
    private List<String> titles = new ArrayList<>(2);

    private MKOfflineMap mOffline = null;

    private OfflineMapManagerAdapter downAdapter;
    private OfflineMapAdapter allSearchAdapter;
    private OfflineExpandableListAdapter allCountryAdapter;

    private List<OfflineMapItem> itemsDown; //下载或下载中城市
    private List<OfflineMapItem> itemsAll;  //所有城市，与热门城市及下载管理对象相同

    private List<OfflineMapItem> itemsProvince;
    private List<List<OfflineMapItem>> itemsProvinceCity;
    private Context context;
    private Button map_offline_down;
    private Button map_offline_city;

    // ----------------------- Constructors ----------------------

    // -------- Methods for/from SuperClass/Interfaces -----------
    private boolean isResumed = false;
    private boolean isWake = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());

        setContentView(R.layout.activity_baidu_offline_map);
        context = this;
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);//设置toolbar
        Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); // 给左上角图标的左边加上一个返回的图标 。
        toolbar.setTitleTextColor(Color.WHITE);
        toolbar.setTitle("添加项目");
        toolbar.setNavigationIcon(R.drawable.back); //代码
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //startActivity(new Intent(context, BottomActivity.class));
                finish();
            }
        });

        // 初始化离线地图管理
        mOffline = new MKOfflineMap();
        mOffline.init(this);

        initViews();

        viewpager.setCurrentItem(1);


    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        if (!isResumed) {
            isResumed = true;
            loadData();
        }
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

        mOffline.destroy();
        finish();
    }

    /**
     * @param type  事件类型: MKOfflineMap.TYPE_NEW_OFFLINE, MKOfflineMap.TYPE_DOWNLOAD_UPDATE, MKOfflineMap.TYPE_VER_UPDATE.
     * @param state 事件状态: 当type为TYPE_NEW_OFFLINE时，表示新安装的离线地图数目. 当type为TYPE_DOWNLOAD_UPDATE时，表示更新的城市ID.
     * @author chenshiqiang E-mail:csqwyyx@163.com
     */
    @Override
    public void onGetOfflineMapState(int type, int state) {
        // TODO Auto-generated method stub
        switch (type) {
            case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:
                MKOLUpdateElement update = mOffline.getUpdateInfo(state);

                if (setElement(update, true) != null) {
                    if (itemsDown != null && itemsDown.size() > 1) {
                        Collections.sort(itemsDown);
                    }

                    refreshDownList();

                } else {
                    downAdapter.notifyDataSetChanged();
                }

                allSearchAdapter.notifyDataSetChanged();
                allCountryAdapter.notifyDataSetChanged();
                break;

            case MKOfflineMap.TYPE_NEW_OFFLINE:
                // 有新离线地图安装
                Log.d("OfflineDemo", String.format("add offlinemap num:%d", state));
                break;

            case MKOfflineMap.TYPE_VER_UPDATE:
                // 版本更新提示
                break;
        }
    }

    /**
     * 百度下载状态改变（暂停--》恢复）居然不回调，所以改变状态时自己得增加接口监听状态改变刷新界面
     *
     * @param item    有状态改变的item
     * @param removed item是否被删除
     * @author chenshiqiang E-mail:csqwyyx@163.com
     */
    @Override
    public void statusChanged(OfflineMapItem item, boolean removed) {
        // TODO Auto-generated method stub
        if (removed) {
            for (int i = itemsDown.size() - 1; i >= 0; i--) {
                OfflineMapItem temp = itemsDown.get(i);
                if (temp.getCityId() == item.getCityId()) {
                    itemsDown.remove(i);
                }
            }
            refreshDownList();

        } else {
            downAdapter.notifyDataSetChanged();
        }

        allSearchAdapter.notifyDataSetChanged();
        allCountryAdapter.notifyDataSetChanged();
    }

    public void toDownloadPage() {
        viewpager.setCurrentItem(0);
    }

    private void initViews() {
        viewpager = findViewById(R.id.viewpager);
        map_offline_down = findViewById(R.id.map_offline_down);
        map_offline_city = findViewById(R.id.map_offline_city);

        map_offline_down.setOnClickListener(this);
        map_offline_city.setOnClickListener(this);
        //pagertab = (PagerTabStrip) findViewById(R.id.pagertab);

        LayoutInflater inf = LayoutInflater.from(this);
        @SuppressLint("InflateParams") View v1 = inf.inflate(R.layout.view_offline_download, null, false);
        svDown = v1.findViewById(R.id.svDown);
        ListView lvDown = v1.findViewById(R.id.lvDown);
        views.add(v1);

        @SuppressLint("InflateParams") View v2 = inf.inflate(R.layout.view_offline_countrys, null, false);
        svAll = v2.findViewById(R.id.svAll);
        lvWholeCountry = v2.findViewById(R.id.lvWholeCountry);
        lvSearchResult = v2.findViewById(R.id.lvSearchResult);
        views.add(v2);


        titles.add("下载管理");
        titles.add("城市列表");

        viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (position == 0) {
                    map_offline_city.setTextColor(Color.rgb(255, 255, 255));
                    map_offline_down.setTextColor(Color.rgb(51, 51, 51));

                    map_offline_city.setBackgroundResource(R.drawable.btn_shape);
                    map_offline_down.setBackgroundResource(R.drawable.btn_shape_white);

                } else if (position == 1) {

                    map_offline_city.setTextColor(Color.rgb(51, 51, 51));
                    map_offline_down.setTextColor(Color.rgb(255, 255, 255));

                    map_offline_down.setBackgroundResource(R.drawable.btn_shape);
                    map_offline_city.setBackgroundResource(R.drawable.btn_shape_white);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        viewpager.setOffscreenPageLimit(2);
        viewpager.setAdapter(new MyPagerAdapter());

        svDown.setSearchListener(new MySearchView.SearchListener() {
            @Override
            public void afterTextChanged(Editable text) {
                refreshDownList();
            }

            @Override
            public void search(String text) {
            }
        });

        svAll.setSearchListener(new MySearchView.SearchListener() {
            @Override
            public void afterTextChanged(Editable text) {
                refreshAllSearchList();
            }

            @Override
            public void search(String text) {
            }
        });

        downAdapter = new OfflineMapManagerAdapter(this, mOffline, this);
        lvDown.setAdapter(downAdapter);

        allSearchAdapter = new OfflineMapAdapter(this, mOffline, this);
        lvSearchResult.setAdapter(allSearchAdapter);

        allCountryAdapter = new OfflineExpandableListAdapter(this, mOffline, this);
        lvWholeCountry.setAdapter(allCountryAdapter);
        lvWholeCountry.setGroupIndicator(null);
    }

    /**
     * 刷新下载列表, 根据搜索关键字及itemsDown
     * 下载管理数量变动时调用
     */
    private void refreshDownList() {
        String key = svDown.getInputText();
        if (key == null || key.length() < 1) {
            downAdapter.setDatas(itemsDown);

        } else {
            List<OfflineMapItem> filterList = new ArrayList<>();
            if (itemsDown != null && !itemsDown.isEmpty()) {
                for (OfflineMapItem i : itemsDown) {
                    if (i.getCityName().contains(key)) {
                        filterList.add(i);
                    }
                }
            }

            downAdapter.setDatas(filterList);
        }
    }

    /**
     * 刷新所有城市搜索结果
     */
    private void refreshAllSearchList() {
        String key = svAll.getInputText();
        if (key == null || key.length() < 1) {
            lvSearchResult.setVisibility(View.GONE);
            lvWholeCountry.setVisibility(View.VISIBLE);

            allSearchAdapter.setDatas(null);

        } else {
            lvSearchResult.setVisibility(View.VISIBLE);
            lvWholeCountry.setVisibility(View.GONE);

            List<OfflineMapItem> filterList = new ArrayList<>();
            if (itemsAll != null && !itemsAll.isEmpty()) {
                for (OfflineMapItem i : itemsAll) {
                    if (i.getCityName().contains(key)) {
                        filterList.add(i);
                    }
                }
            }

            allSearchAdapter.setDatas(filterList);
        }
    }

    @SuppressLint("StaticFieldLeak")
    private void loadData() {

        new CsqBackgroundTask<Void>(this) {
            @Override
            protected Void onRun() {

                // 导入离线地图包
                // 将从官网下载的离线包解压，把vmp文件夹拷入SD卡根目录下的BaiduMapSdk文件夹内。
                // 把网站上下载的文件解压，将\BaiduMap\vmp\l里面的.dat_svc文件，拷贝到手机BaiduMapSDK/vmp/h目录下
                int num = mOffline.importOfflineData();
                if (num > 0) {
                    ToastUtil.showToastInfo(BaiduOfflineMapActivity.this, "成功导入" + num + "个离线包", false);
                }

                List<MKOLSearchRecord> all = null;
                try {
                    all = mOffline.getOfflineCityList();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (all == null || all.isEmpty()) {
                    ToastUtil.showToastInfo(BaiduOfflineMapActivity.this,
                            "未获取到离线地图城市数据，可能有其他应用正在使用百度离线地图功能！", false);
                    return null;
                }

                List<MKOLSearchRecord> hotCity = mOffline.getHotCityList();
                HashSet<Integer> hotCityIds = new HashSet<>();
                if (!hotCity.isEmpty()) {
                    for (MKOLSearchRecord r : hotCity) {
                        hotCityIds.add(r.cityID);
                    }
                }

                itemsAll = new ArrayList<>();
                itemsDown = new ArrayList<>();
                itemsProvince = new ArrayList<>();
                itemsProvinceCity = new ArrayList<>();

                //cityType  0:全国；1：省份；2：城市,如果是省份，可以通过childCities得到子城市列表

                //全国概略图、直辖市、港澳 子城市列表
                ArrayList<MKOLSearchRecord> childMunicipalities = new ArrayList<>();
                ArrayList<OfflineMapItem> childHotCitys = new ArrayList<>();

                for (MKOLSearchRecord province : all) {
                    OfflineMapItem item = new OfflineMapItem();
                    item.setCityInfo(province);

                    List<MKOLSearchRecord> childs = province.childCities;
                    if (childs != null && !childs.isEmpty()) {
                        //省

                        List<OfflineMapItem> itemList = new ArrayList<>();
                        for (MKOLSearchRecord itemCity : childs) {
                            OfflineMapItem c = new OfflineMapItem();
                            c.setCityInfo(itemCity);
                            itemList.add(c);

                            itemsAll.add(c);
                            if (hotCityIds.contains(itemCity.cityID)) {
                                //添加到热门城市，保证与省份下的城市是一个对象
                                childHotCitys.add(c);
                            }
                        }
                        itemsProvinceCity.add(itemList);
                        itemsProvince.add(item);

                    } else {
                        //全国概略图、直辖市、港澳
                        childMunicipalities.add(province);
                    }
                }

                //构建一个省份，放全国概略图、直辖市、港澳
                if (!childMunicipalities.isEmpty()) {
                    MKOLSearchRecord proMunicipalities = new MKOLSearchRecord();
                    proMunicipalities.cityName = "全国概略图、直辖市、港澳";
                    proMunicipalities.childCities = childMunicipalities;
                    proMunicipalities.cityType = 1;

                    List<OfflineMapItem> itemList = new ArrayList<>();
                    for (MKOLSearchRecord itemCity : childMunicipalities) {
                        OfflineMapItem c = new OfflineMapItem();
                        c.setCityInfo(itemCity);
                        itemList.add(c);

                        proMunicipalities.size += itemCity.size;
                        itemsAll.add(c);
                        if (hotCityIds.contains(itemCity.cityID)) {
                            //添加到热门城市，保证与省份下的城市是一个对象
                            childHotCitys.add(c);
                        }
                    }

                    OfflineMapItem item = new OfflineMapItem();
                    item.setCityInfo(proMunicipalities);
                    itemsProvinceCity.add(0, itemList);
                    itemsProvince.add(0, item);
                }

                //构建一个省份，放热门城市
                if (!childHotCitys.isEmpty()) {
                    int size = 0;
                    ArrayList<MKOLSearchRecord> cs = new ArrayList<>();
                    for (OfflineMapItem i : childHotCitys) {
                        cs.add(i.getCityInfo());
                        size += i.getSize();
                    }

                    MKOLSearchRecord proHot = new MKOLSearchRecord();
                    proHot.cityName = "热门城市";
                    proHot.childCities = cs;
                    proHot.cityType = 1;
                    proHot.size = size;

                    OfflineMapItem item1 = new OfflineMapItem();
                    item1.setCityInfo(proHot);
                    itemsProvinceCity.add(0, childHotCitys);
                    itemsProvince.add(0, item1);
                }

                // 刷新状态
                List<MKOLUpdateElement> updates = mOffline.getAllUpdateInfo();
                if (updates != null && updates.size() > 0) {
                    for (MKOLUpdateElement element : updates) {
                        setElement(element, false);
                    }

                    if (itemsDown != null && itemsDown.size() > 1) {
                        Collections.sort(itemsDown);
                    }
                }

                return null;
            }

            @Override
            protected void onResult(Void result) {
                // TODO Auto-generated method stub
                refreshDownList();
                refreshAllSearchList();

                allCountryAdapter.setDatas(itemsProvince, itemsProvinceCity);
            }
        }.execute();
    }

    /**
     * 返回itemsDown.add
     */
    private OfflineMapItem setElement(MKOLUpdateElement element, boolean ischeck) {
        OfflineMapItem ret = null;

        if (element == null || itemsAll == null) {
            return null;
        }

        if (element.status == MKOLUpdateElement.DOWNLOADING && element.ratio == 100) {
            element.status = MKOLUpdateElement.FINISHED;
        }

        for (OfflineMapItem item : itemsAll) {
            if (element.cityID == item.getCityId()) {
                item.setDownInfo(element);

                // 过滤已下载数据
                if (item.getStatus() != MKOLUpdateElement.UNDEFINED) {
                    if (ischeck) {
                        if (!itemsDown.contains(item)) {
                            if (itemsDown.add(item)) {
                                ret = item;
                            }
                        }

                    } else {
                        if (itemsDown.add(item)) {
                            ret = item;
                        }
                    }
                }
                if (!isWake && item.getStatus() == MKOLUpdateElement.WAITING) {
                    int id = item.getCityId();
                    if (id > 0) {
                        mOffline.start(id);
                    }
                    isWake = true;
                }
                break;
            }
        }

        return ret;
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.map_offline_down:
                viewpager.setCurrentItem(0);
                map_offline_city.setTextColor(Color.rgb(255, 255, 255));
                map_offline_down.setTextColor(Color.rgb(51, 51, 51));
                map_offline_city.setBackgroundResource(R.drawable.btn_shape);
                map_offline_down.setBackgroundResource(R.drawable.btn_shape_white);
                break;
            case R.id.map_offline_city:
                viewpager.setCurrentItem(1);
                map_offline_city.setTextColor(Color.rgb(51, 51, 51));
                map_offline_down.setTextColor(Color.rgb(255, 255, 255));
                map_offline_down.setBackgroundResource(R.drawable.btn_shape);
                map_offline_city.setBackgroundResource(R.drawable.btn_shape_white);
                break;
        }
    }

    // --------------------- Getter & Setter ---------------------

    // --------------- Inner and Anonymous Classes ---------------


    class MyPagerAdapter extends PagerAdapter {

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            // TODO Auto-generated method stub
            View v = views.get(position);
            container.addView(v);
            return v;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            // TODO Auto-generated method stub
            container.removeView(views.get(position));
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return views.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // TODO Auto-generated method stub
            return titles.get(position);
        }

    }

}
